package vip.aster.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.PostConstruct;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import vip.aster.common.exception.BusinessException;
import vip.aster.common.utils.PageInfo;
import vip.aster.framework.i18n.MessageUtils;
import vip.aster.system.entity.SysDictData;
import vip.aster.system.entity.SysDictType;
import vip.aster.system.mapper.SysDictTypeMapper;
import vip.aster.system.query.SysDictTypeQuery;
import vip.aster.system.service.SysDictDataService;
import vip.aster.system.service.SysDictTypeService;
import vip.aster.system.utils.DictUtils;
import vip.aster.system.vo.SysDictDataVO;
import vip.aster.system.vo.SysDictTypeVO;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 字典类型 服务实现类
 * </p>
 *
 * @author Aster
 * @since 2023-11-28 10:36
 */
@Service
@AllArgsConstructor
public class SysDictTypeServiceImpl extends ServiceImpl<SysDictTypeMapper, SysDictType> implements SysDictTypeService {
    private SysDictTypeMapper sysDictTypeMapper;
    private SysDictDataService sysDictDataService;

    @PostConstruct
    public void init() {
        // 加载字典到缓存中
        loadingDictCache();
    }

    private void loadingDictCache() {
        List<SysDictType> dictTypeList = this.list();
        for (SysDictType dictType : dictTypeList) {
            List<SysDictData> dataList = sysDictDataService.getDataByTypId(dictType.getId());
            DictUtils.setDictCache(dictType.getDictType(), dataList);
        }
    }

    @Override
    public List<SysDictTypeVO> getDictAll() {
        // 全部字典类型列表
        List<SysDictType> typeList = this.list();

        // 全部字典数据列表
        LambdaQueryWrapper<SysDictData> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByAsc(SysDictData::getSort);
        List<SysDictData> dataList = sysDictDataService.list(queryWrapper);

        // 全部字典列表
        List<SysDictTypeVO> dictList = new ArrayList<>(typeList.size());
        for (SysDictType type : typeList) {
            SysDictTypeVO dict = new SysDictTypeVO(type);

            for (SysDictData data : dataList) {
                if (type.getId().equals(data.getDictTypeId())) {
                    dict.getDataList().add(new SysDictDataVO(data));
                }
            }
            dictList.add(dict);
        }
        return dictList;
    }

    @Override
    public PageInfo<SysDictTypeVO> pageList(SysDictTypeQuery query) {
        Page<SysDictType> page = new Page<>(query.getPageNum(), query.getPageSize());
        Page<SysDictType> pageList = this.page(page, getWrapper(query));
        return new PageInfo<>(SysDictTypeVO.convertList(pageList.getRecords()), pageList.getTotal());
    }

    @Override
    public void saveType(SysDictTypeVO dictTypeVO) {
        SysDictType dictType = new SysDictType();
        BeanUtil.copyProperties(dictTypeVO, dictType, true);
        // 校验字典类型是否唯一
        if (!checkDictTypeUnique(dictType.getId(), dictType.getDictType())) {
            throw new BusinessException(MessageUtils.message("dict.type.unique"));
        }
        if (StrUtil.isNotBlank(dictType.getId())) {
            sysDictTypeMapper.updateById(dictType);
            // 更新缓存
            List<SysDictData> dataList = sysDictDataService.getDataByTypId(dictType.getId());
            DictUtils.setDictCache(dictType.getDictType(), dataList);
        } else {
            sysDictTypeMapper.insert(dictType);
            // 加入缓存中
            DictUtils.setDictCache(dictType.getDictType(), new ArrayList<>());
        }
    }

    @Override
    public void removeDictTypByIds(List<String> ids) {
        for (String dictId : ids) {
            SysDictType dictType = this.getById(dictId);
            if (CollUtil.isNotEmpty(sysDictDataService.getDataByTypId(dictId))) {
                throw new BusinessException(String.format(MessageUtils.message("dict.type.delete"), dictType.getDictName()));
            }
            this.removeById(dictId);
            DictUtils.removeDictCache(dictType.getDictType());
        }
    }

    private Wrapper<SysDictType> getWrapper(SysDictTypeQuery query) {
        LambdaQueryWrapper<SysDictType> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StrUtil.isNotBlank(query.getDictType()), SysDictType::getDictType, query.getDictType());
        wrapper.like(StrUtil.isNotBlank(query.getDictName()), SysDictType::getDictName, query.getDictName());
        wrapper.eq(StrUtil.isNotBlank(query.getStatus()), SysDictType::getStatus, query.getStatus());
        wrapper.orderByAsc(SysDictType::getSort);
        return wrapper;
    }

    /**
     * 校验字典类型是否唯一
     *
     * @param id       字典类型id
     * @param dictType 类型名称
     * @return true-唯一, false-否
     */
    private Boolean checkDictTypeUnique(String id, String dictType) {
        LambdaQueryWrapper<SysDictType> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysDictType::getDictType, dictType);
        SysDictType obj = sysDictTypeMapper.selectOne(queryWrapper);
        if (obj != null) {
            return StrUtil.equals(id, obj.getId());
        }
        return true;
    }

}
